import com.google.gdata.client.http.AuthSubUtil
import com.googlecode.linkmein.domain.*
import com.googlecode.linkmein.repository.ObjectStorage
import com.googlecode.linkmein.service.DateFormatter
import com.googlecode.linkmein.service.FetchEmployeeService
import com.googlecode.linkmein.service.GmailContactsService
import grails.converters.JSON

public class DashboardController {
  FetchEmployeeService fetchEmployeeService
  ObjectStorage storage
  GmailContactsService gmailContactsService

  def beforeInterceptor = {
    if (params.token) {
      String sessionToken = AuthSubUtil.exchangeForSessionToken(params.token.toString(), null)
      gmailContactsService.setUpService(sessionToken)
      String gmail = gmailContactsService.getGmail()
      Employees employees = fetchEmployeeService.getEmployees()
      Employee currentUser = employees.findByGmail(gmail)
      if (currentUser && currentUser != currentUser.NULL) {
        session.setAttribute("gmail", gmail)
        session.setAttribute("englishName", currentUser.getEnglishName())
        session.setAttribute("shrinkedEnglishName", currentUser.getShrinkedEnglishName())
        session.setAttribute("token", sessionToken)
        redirect(action: index)
      }
    }
    if (!session.getAttribute("gmail")) {
      flash["error"] = "Please login with your google account and make sure your google account is in our list."
      redirect(uri: "/error.gsp")
      return false
    }
    return true
  }

  def index = {
    Projects projects = fetchEmployeeService.getProjects()
    Employees employees = fetchEmployeeService.getEmployees()
    render(view: "index", model: [
            changes: groupChangesByTime(storage.findAllChanges(15)),
            projectNumber: projects.size(),
            employeeNumber: employees.size(),
            firstProject: projects.get(0),
            firstEmployee: employees.get(0)
    ])
  }

  def map = {
    Employees employees = fetchEmployeeService.getEmployees()
    render contentType: 'text/plain', text: [employees: flatten(employees)] as JSON
  }

  def editmapinfo = {
    Employees employees = fetchEmployeeService.getEmployees()
    def employee = employees.findByName(new Name(params.employeeName, "only compare english name"))
    MapInfo mapInfo = new MapInfo(params.employeeLat.toDouble(), params.employeeLng.toDouble(), params.employeeAddress, params.employeeName, params.type)
    employee.setMapInfo(mapInfo)
    storage.store(mapInfo)
    redirect(action: index)
  }

  def updatecontacts = {
    gmailContactsService.createContactsForCurrentUser(fetchEmployeeService)
    redirect(action: index)
  }

  def logout = {
    session.removeAttribute("gmail")
    String sessionToken = session.getAttribute("token").toString()
    AuthSubUtil.revokeToken(sessionToken, null)
    redirect(url: "https://www.google.com/accounts/Logout")
  }

  private def groupChangesByTime(changeList) {
    def changes = [:]
    for (change in changeList) {
      String date = DateFormatter.format(change.createdAt)
      if (!changes.containsKey(date)) {
        changes[date] = [];
      }
      else {
        changes[date].add(change.toString(
                {employee -> link(controller: "workmates", action: "show", params: [name: employee.shrinkedEnglishName]) {employee.englishName}},
                {name -> link(controller: "projects", action: "show", params: [name: name]) {name}}))
      }
    }
    return changes
  }

  private Object flatten(Employees employees) {
    if (employees.size() == 0)
      return "[]";

    def result = []
    employees.each {
      result.add(flatten(it))
    }
    return result;
  }

  private Object flatten(Employee e) {
    String address = e.getMapInfo().getAddress();
    double lat = e.getMapInfo().getLat();
    double lng = e.getMapInfo().getLng();

    return [
            englishName: e.englishName,
            shrinkedEnglishName: e.shrinkedEnglishName,
            chineseName: e.chineseName,
            address: address,
            lat: lat,
            lng: lng,
            cellphone: e.getCellphone()
    ];
  }

}